<?php

	define ('E_OK',				1);
	define ('E_ERROR_FORM',		2);
	define ('E_ERROR_PROC',		3);

	// *****************************************************************************************************
	// Cambiar el modo de reporte de errores para evitar los mensajes tipo "notice" y "deprecated".
	error_reporting (E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_WARNING);

	// Variables globales para la guardar la respuesta y la lista de funciones publicadas.
	$RESPUESTA = array('respuesta' => E_OK);
	$FUNCIONES = array();
	$CWD = getcwd();

	// *****************************************************************************************************
	// Agrega un valor al mapa (array-asociativo) de respuesta. Esta función se utiliza unicamente para
	// hacer más sencillo el trabajo de retornar datos al cliente. Una vez que todos los datos hayan sido
	// agregados al mapa de respuesta deberá ejecutar ret() para enviar los datos al cliente.

	function resp ($nombre, $valor)
	{
		global $RESPUESTA;
		$RESPUESTA[$nombre] = $valor;
	}

	// *****************************************************************************************************
	// Envía el mapa de respuesta al cliente y finaliza la ejecucion inmediatamente. Para agregar datos al
	// mapa de respuesta debe utilizar la función resp(). Si se utiliza resp() con el parámetro $err entonces
	// se agregará automaticamente una variable 'respuesta' con el valor de $err.

	function ret ($err)
	{
		global $RESPUESTA;

		if ($err) $RESPUESTA['respuesta'] = $err;

		echo json_encode ($RESPUESTA);
		exit;
	}

	// *****************************************************************************************************
	// Envia una respuesta de error al cliente y finaliza la ejecución. El parámetro $err indica la string
	// de error que será enviada al cliente, debe utilizas las constantes del archivo def_errores.php. Si se
	// utiliza tambien el parametro $msg se agregara un campo 'mensaje' en la respuesta.

	function reterr ($err, $msg)
	{
		$resp = array('respuesta' => $err);
		if ($msg) $resp['mensaje'] = $msg;
		echo json_encode ($resp);
		exit;
	}

	// *****************************************************************************************************
	// Valida datos de entrada ($datos) utilizando la información dada $info. Este último es un mapa cuyo
	// indice es el nombre de la variable a validar y su valor es un arreglo con el metodo de validación.

	// Tipos de validacion soportado hasta ahora son:
	
	//	'obligatorio' => array (es_obligatorio, mensaje_error)
	//	Indica si el campo es obligatorio con el parametro "es_obligatorio" (bool).

	//	'min_longitud' => array (num_chars, mensaje_error)
	//	Verifica que la longitud del campo sea al menos "num_chars" (int).

	//	'max_longitud' => array (num_chars, mensaje_error)
	//	Verifica que la longitud del campo sea a lo maximo "num_chars" (int).

	//	'numerico' => array (mensaje_error)
	//	Verifica que el campo sea numerico.

	//	'pertenece' => array (arreglo_opciones, mensaje_error)
	//	Verifica que el campo pertenezca al arreglo de opciones dado.

	//	'pattern' => array (regex, mensaje_error)
	//	Verifica que el campo usando una expresión regular.

	function validar ($datos, $info)
	{
		$validado = array();
		$error = false;

		foreach ($info as $campo => $validacion)
		{
			$valor = trim($datos[$campo]);

			try
			{
				foreach ($validacion as $nombre => $args)
				{
					switch ($nombre)
					{
						case 'obligatorio':
							if (!strlen($valor)) throw new Exception ($args[0] === true ? $args[1] : '');
							break;

						case 'min_longitud':
							if (strlen($valor) < $args[0]) throw new Exception ($args[1]);
							break;

						case 'max_longitud':
							if (strlen($valor) > $args[0]) throw new Exception ($args[1]);
							break;

						case 'numerico':
							if (!is_numeric($valor)) throw new Exception ($args[0]);
							break;

						case 'pertenece':
							if (array_search($valor, $args[0]) === false) throw new Exception ($args[1]);
							break;

						case 'pattern':
							if (!preg_match('~^'.$args[0].'$~', $valor)) throw new Exception ($args[1]);
							break;
					}
				}
			}
			catch (Exception $e)
			{
				$msg = $e->getMessage();
				if ($msg != null)
				{
					resp ($campo, $msg);
					$error = true;
					continue;
				}
				else
				{
					$valor = null;
				}
			}

			$validado[$campo] = $valor;
		}

		if ($error) ret(E_ERROR_FORM);

		return $validado;
	}

	// *****************************************************************************************************
	// Retorna NULL si la cadena es null o vacia.

	function ifNullOrEmpty ($value)
	{
		return $value === null || !strlen($value) ? null : $value;
	}
